package com.fand.site.dao;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.joda.time.DateTime;

import com.fand.dto.PaginationDto;
import com.fand.persistent.builder.ModelArgs;
import com.fand.persistent.builder.ModelBuilder;
import com.fand.persistent.builder.ModelBuilderUtils;
import com.fand.persistent.support.JdbcDaoSupport;
import com.fand.site.dto.DomainNaDto;
import com.fand.site.dto.SiteDeDto;
import com.fand.site.dto.SiteDto;
import com.google.common.collect.Maps;

/**
 * 站
 * 
 * @author yaoHT
 */
public class JdbcSiteDao extends JdbcDaoSupport implements SiteDao {
	@Override
	public int deleteDomainNaBy1(final String id) {
		final ModelBuilder deleteModelBuilder = ModelBuilderUtils.newModelBuilder().putExtend(null, "id", null,
		        id);
		
		return this.update("site/domainNa/deleteDomainNaBy1", deleteModelBuilder.build());
	}
	
	@Override
	public int deleteDomainNaByIds(final String ids) {
		final Map<String, Object> model = Maps.newHashMap();
		
		model.put("IDS", ids);
		
		return this.update("site/domainNa/deleteDomainNaBy101", model);
	}
	
	@Override
	public int deleteSiteBy1(final String id) {
		final ModelBuilder deleteModelBuilder = ModelBuilderUtils.newModelBuilder().putExtend(null, "id", null,
		        id);
		
		return this.update("site/site/deleteSiteBy1", deleteModelBuilder.build());
	}
	
	@Override
	public int deleteSiteBy1(final String[] ids) {
		final String idsString = StringUtils.join(ids, ",");
		
		return this.deleteSiteByIds(idsString);
	}
	
	@Override
	public int deleteSiteByIds(final String ids) {
		final Map<String, Object> model = Maps.newHashMap();
		
		model.put("IDS", ids);
		
		return this.update("site/site/deleteSiteBy101", model);
	}
	
	@Override
	public int deleteSiteDeBy1(final String entityId) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder().putExtend(null, "entityId", null,
		        entityId);
		
		return this.update("site/siteDe/deleteSiteDeBy1", modelBuilder.build());
	}
	
	@Override
	public int deleteSiteDeByNQSiteId(final String entityId) {
		final Map<String, Object> model = Maps.newHashMap();
		
		model.put("ENTITY_ID", entityId);
		
		return this.update("site/siteDe/deleteSiteDeByNQSiteId", model);
	}
	
	@Override
	public PaginationDto<Map<String, Object>> paginationDomainNaBy1ForMapList(final DomainNaDto domainNa) {
		final Map<String, Object> model = Maps.newHashMap();
		
		model.put("CODE", domainNa.getCode());
		
		model.put("SITE_ID", domainNa.getSiteId());
		
		return this.paginationForMapList("site/domainNa/selectDomainNaBy101ForObject",
		        "site/domainNa/selectDomainNaBy101ForMappedObjectList", domainNa.getPaginationNo(),
		        domainNa.getPaginationSize(), model);
	}
	
	@Override
	public PaginationDto<Map<String, Object>> paginationSiteBy1ForMapList(final SiteDto site) {
		final Map<String, Object> model = Maps.newHashMap();
		
		model.put("CODE", site.getCode());
		model.put("DOMAIN_NA_CODE", site.getDomainNaCo());
		
		return this.paginationForMapList("site/site/selectSiteBy101ForObject",
		        "site/site/selectSiteBy101ForMappedObjectList", site.getPaginationNo(), site.getPaginationSize(),
		        model);
	}
	
	@Override
	public String saveDomainNaBy1ForObject(final DomainNaDto domainNa) {
		final ModelBuilder selectModelBuilder = ModelBuilderUtils.newModelBuilder();
		
		if (StringUtils.isNotBlank(domainNa.getId())) {
			selectModelBuilder.putExtend(null, "id", null, domainNa.getId());
		} else {
			selectModelBuilder.putExtend(null, "code", null, domainNa.getCode());
		}
		
		final DomainNaDto oldDomainNa = this.selectForMappedObject(DomainNaDto.class,
		        "site/domainNa/selectDomainNaBy1ForMappedObjectList", selectModelBuilder.build());
		
		if (oldDomainNa == null) {
			final Date deginDaTi = new Date();
			final DateTime endDaTi = new DateTime(9999, 12, 31, 0, 0, 0, 0);
			
			domainNa.setBeginDaTi(deginDaTi);
			domainNa.setEndDaTi(endDaTi.toDate());
			domainNa.setId(UUID.randomUUID().toString());
			
			final ModelBuilder insertModelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(
			        ModelBuilder.INSERT, domainNa));
			
			this.update("site/domainNa/insertDomainNaBy1", insertModelBuilder.build());
			
			return domainNa.getId();
		}
		
		do {
			if (!StringUtils.equals(oldDomainNa.getName(), domainNa.getName())) {
				break;
			}
			
			if (StringUtils.isNotBlank(domainNa.getId())) {
				if (!StringUtils.equals(oldDomainNa.getCode(), domainNa.getCode())) {
					break;
				}
			}
			
			if (!StringUtils.equals(oldDomainNa.getSiteId(), domainNa.getSiteId())) {
				break;
			}
			
			if (!(NumberUtils.compare(oldDomainNa.getOrderNum(), domainNa.getOrderNum()) == 0)) {
				break;
			}
			
			return oldDomainNa.getId();
		} while (false);
		
		final ModelArgs updateModelArgs = new ModelArgs(ModelBuilder.UPDATE, domainNa, "name");
		
		if (StringUtils.isNotBlank(domainNa.getId())) {
			updateModelArgs.setUseProperties("name", "code", "siteId", "orderNum");
		}
		
		final ModelBuilder updateModelBuilder = ModelBuilderUtils.newModelBuilder(updateModelArgs).putExtend(
		        null, "id", null, oldDomainNa.getId());
		
		this.update("site/domainNa/updateDomainNaBy1", updateModelBuilder.build());
		
		return oldDomainNa.getId();
	}
	
	@Override
	public String saveSiteBy1ForObject(final SiteDto site) {
		final ModelBuilder selectModelBuilder = ModelBuilderUtils.newModelBuilder();
		
		if (StringUtils.isNotBlank(site.getId())) {
			selectModelBuilder.putExtend(null, "id", null, site.getId());
		} else {
			selectModelBuilder.putExtend(null, "code", null, site.getCode());
		}
		
		final SiteDto oldSite = this.selectForMappedObject(SiteDto.class,
		        "site/site/selectSiteBy1ForMappedObjectList", selectModelBuilder.build());
		
		if (oldSite == null) {
			final Date deginDaTi = new Date();
			final DateTime endDaTi = new DateTime(9999, 12, 31, 0, 0, 0, 0);
			
			site.setBeginDaTi(deginDaTi);
			site.setEndDaTi(endDaTi.toDate());
			site.setId(UUID.randomUUID().toString());
			
			final ModelBuilder insertModelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(
			        ModelBuilder.INSERT, site));
			
			this.update("site/site/insertSiteBy1", insertModelBuilder.build());
			
			return site.getId();
		}
		
		do {
			if (!StringUtils.equals(oldSite.getName(), site.getName())) {
				break;
			}
			
			if (StringUtils.isNotBlank(site.getId())) {
				if (!StringUtils.equals(oldSite.getCode(), site.getCode())) {
					break;
				}
			}
			
			return oldSite.getId();
		} while (false);
		
		final ModelArgs updateModelArgs = new ModelArgs(ModelBuilder.UPDATE, site, "name");
		
		if (StringUtils.isNotBlank(site.getId())) {
			updateModelArgs.setUseProperties("name", "code");
		}
		
		final ModelBuilder updateModelBuilder = ModelBuilderUtils.newModelBuilder()
		        .putExtend(null, "id", null, oldSite.getId()).putObjectField(updateModelArgs);
		
		this.update("site/site/updateSiteBy1", updateModelBuilder.build());
		
		return oldSite.getId();
	}
	
	@Override
	public int saveSiteDeBy1(final SiteDeDto siteDe) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder().putExtend(null, "entityId", null,
		        siteDe.getEntityId());
		
		final int count = this.selectForObject(Integer.class, "site/siteDe/selectSiteDeBy1ForObject", null,
		        modelBuilder.build());
		
		if (count > 0) { return 0; }
		
		final Date deginDaTi = new Date();
		final DateTime endDaTi = new DateTime(9999, 12, 31, 0, 0, 0, 0);
		
		siteDe.setBeginDaTi(deginDaTi);
		siteDe.setEndDaTi(endDaTi.toDate());
		siteDe.setId(UUID.randomUUID().toString());
		
		modelBuilder.putObjectField(new ModelArgs(ModelBuilder.INSERT, siteDe));
		
		return this.update("site/siteDe/insertSiteDeBy1", modelBuilder.build());
	}
	
	@Override
	public DomainNaDto selectDomainNaBy1ForMappedObject(final String id) {
		final Map<String, Object> model = Maps.newHashMap();
		
		model.put("ID", id);
		
		final DomainNaDto domainNa = this.selectForMappedObject(DomainNaDto.class,
		        "site/domainNa/selectDomainNaBy102ForMappedObjectList", model);
		
		return domainNa;
	}
	
	@Override
	public int selectDomainNaByIdAndCodeForObject(final String id, final String code) {
		final Map<String, Object> model = Maps.newHashMap();
		
		model.put("ID", id);
		model.put("CODE", code);
		
		return this.selectForObject(Integer.class, "site/domainNa/selectDomainNaBy201ForObject", null, model);
	}
	
	@Override
	public SiteDto selectSiteBy1ForMappedObject(final String id) {
		final Map<String, Object> model = Maps.newHashMap();
		
		model.put("ID", id);
		
		final SiteDto site = this.selectForMappedObject(SiteDto.class,
		        "site/site/selectSiteBy102ForMappedObjectList", model);
		
		return site;
	}
	
	@Override
	public List<SiteDto> selectSiteBy1ForMappedObjectList() {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder().putExtend("order__by", "code",
		        null, "ASC");
		
		return this.selectForMappedObjectList(SiteDto.class, "site/site/selectSiteBy1ForMappedObjectList",
		        modelBuilder.build());
	}
	
	@Override
	public SiteDto selectSiteBy2ForMappedObject(final String domainUrl) {
		final Map<String, Object> model = Maps.newHashMap();
		
		model.put("CODE", domainUrl);
		
		final SiteDto site = this.selectForMappedObject(SiteDto.class, "site/site/selectSiteBy2ForMappedObject",
		        model);
		
		return site;
	}
	
	@Override
	public SiteDto selectSiteByDefaultForMappedObject() {
		final Map<String, Object> model = Maps.newHashMap();
		
		final SiteDto site = this.selectForMappedObject(SiteDto.class,
		        "site/site/selectSiteByDefaultForMappedObject", model);
		
		return site;
	}
	
	@Override
	public int selectSiteByIdAndCodeForObject(final String id, final String code) {
		final Map<String, Object> model = Maps.newHashMap();
		
		model.put("ID", id);
		model.put("CODE", code);
		
		return this.selectForObject(Integer.class, "site/site/selectSiteBy201ForObject", null, model);
	}
}